package com.bes.bessdk.service;

import static com.bes.bessdk.BesSdkConstants.BES_BLE_OTA_AUTO_TEST;
import static com.bes.bessdk.BesSdkConstants.BES_BLE_OTA_AUTO_TEST_VALUE;
import static com.bes.bessdk.BesSdkConstants.BES_CONNECT_ERROR;
import static com.bes.bessdk.BesSdkConstants.BES_CONNECT_SUCCESS;
import static com.bes.bessdk.BesSdkConstants.BES_NOTIFY_ERROR;
import static com.bes.bessdk.BesSdkConstants.BES_NOTIFY_SUCCESS;
import static com.bes.bessdk.service.BesOTAConstants.BES_OTA_IS_MULTIDEVICE_UPGRADE;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_CHECK_BREAK_POINT_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_PROTOCOL_VERSION_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_RANDOMID_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_SELECT_SIDE_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_UPGRATE_TYPE_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_GET_VERSION_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_OTA_OVER_RECONNECT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_SET_OTA_CONFIG_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_SET_USER_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_START_OTA_PACKAGE_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.MSG_VERIFY_BTH_TIME_OUT;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_ADJUST_INTERVAL;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_BREAKPOINT_CHECK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_BREAKPOINT_CHECK_80;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_BREAKPOINT_CHECK_80_NO_CHANGE;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_CRC_CHECK_PACKAGE_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_CRC_CHECK_PACKAGE_OK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_DISCONNECT;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_GET_HW_INFO;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_GET_PROTOCOL_VERSION;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_IMAGE_OVER_CONFIRM_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_RETURN;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_ROLESWITCH_GET_RANDOMID;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SELECT_SIDE_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SELECT_SIDE_OK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SEND_82;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SEND_CONFIGURE_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SEND_CONFIGURE_OK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SEND_OTA_DATA;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SEND_VERIFY_BTN_OK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SET_OAT_USER_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SET_OAT_USER_OK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SET_UPGRADE_TYPE_FAST;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_SET_UPGRADE_TYPE_NORMAL;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_WHOLE_CRC_CHECK;
import static com.bes.bessdk.service.BesOTAConstants.OTA_CMD_WHOLE_CRC_CHECK_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_SEND_DATA_PROGRESS;
import static com.bes.bessdk.service.BesOTAConstants.OTA_START_DEVICE_LOW_BATTERY_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.OTA_START_OTA_ERROR;
import static com.bes.bessdk.service.BesOTAConstants.USER_MULTIPLE;
import static com.bes.sdk.utils.DeviceProtocol.PROTOCOL_BLE;
import static com.bes.sdk.utils.OTAStatus.STATUS_CANCELED;
import static com.bes.sdk.utils.OTAStatus.STATUS_FAILED;
import static com.bes.sdk.utils.OTAStatus.STATUS_PAUSED;
import static com.bes.sdk.utils.OTAStatus.STATUS_REBOOT;
import static com.bes.sdk.utils.OTAStatus.STATUS_STARTED;
import static com.bes.sdk.utils.OTAStatus.STATUS_SUCCEED;
import static com.bes.sdk.utils.OTAStatus.STATUS_UNKNOWN;
import static com.bes.sdk.utils.OTAStatus.STATUS_UPDATING;
import static com.bes.sdk.utils.OTAStatus.STATUS_VERIFIED;
import static com.bes.sdk.utils.OTAStatus.STATUS_VERIFYING;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

import com.bes.bessdk.scan.BtHeleper;
import com.bes.bessdk.service.base.BesBaseService;
import com.bes.bessdk.service.base.BesServiceConfig;
import com.bes.bessdk.service.base.BesServiceListener;
import com.bes.bessdk.utils.ArrayUtil;
import com.bes.bessdk.utils.SPHelper;
import com.bes.sdk.connect.DeviceConnector;
import com.bes.sdk.device.HmDevice;
import com.bes.sdk.message.BaseMessage;
import com.bes.sdk.ota.OTADfuInfo;
import com.bes.sdk.ota.OTATask;
import com.bes.sdk.ota.RemoteOTAConfig;
import com.bes.sdk.utils.DeviceProtocol;
import com.bes.sdk.utils.OTAStatus;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

public class BesOtaService extends BesBaseService implements DeviceConnector.ConnectionListener, OTATask {
    protected final Object mOtaLock = new Object();
    private final int OTA_TIME_OUT = 500;
    private byte[][] curPacketData = null;
    private int curSendCount = 0;
    private int curSendLength = 0;
    private int curOtaResult = 0;
    private int notifyRetryTimes = 0;
    private int connectRetryTimes = 0;
    private int getVersionRetryTimes = 0;
    private int getCrcConfirmRetryTimes = 0;
    private int getProtocolRetryTimes = 0;
    private int setUserRetryTimes = 0;
    private boolean sendPackageWithAck = false;
    private int crcPackageRetryTimes = 0;
    private int USER_FLAG = 1;
    private boolean currentOrLegacy = true;
    private int curUpgateType = 1;
    private int curUser = 1;// 1:fw 2:language 3:combine
    private long sppSendDataDelay = 10;
    private long confirmSendDataDelay = 0;
    private int imageSideSelection = 0;
    // spp role switch
    private int sppRoleSwitchTimes = 0;
    private boolean isWithoutResponse = false;
    private boolean roleSwitchDisconnect = false;
    private boolean isSppRoleSwitch = false;
    private boolean scanSuccess = false;
    private String roleSwitchRandomID = "";
    private String progress = "0.00";
    private Timer sppRoleSwitchTimer;
    private TimerTask task;
    private BesOtaCMD mOtaCMD;
    private BluetoothDevice mDevice;
    private RemoteOTAConfig mRemoteOTAConfig;
    private OTAStatus mOTAStatus = STATUS_UNKNOWN;
    private OTADfuInfo mOTADfuInfo;
    private BluetoothLeScanner mLeScanner;
    private StatusListener mStatusListener;

    public BesOtaService(BesServiceConfig serviceConfig, BesServiceListener listener, Context context) {
        super(serviceConfig, listener, context);
        LOG(TAG, "init");
        String address = mConfig.getDeviceProtocol() == PROTOCOL_BLE ? mConfig.getDevice().getBleAddress()
                : mConfig.getDevice().getDeviceMAC();
        if (address != null && !address.isEmpty()) {
            mDevice = BtHeleper.getBluetoothAdapter(mContext).getRemoteDevice(address);
        }
        USER_FLAG = serviceConfig.getUSER_FLAG();
        isWithoutResponse = serviceConfig.getIsWithoutResponse();
        mOtaCMD = new BesOtaCMD();
        mOtaCMD.setOtaUser(USER_FLAG, serviceConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_SPP,
                isWithoutResponse, mConfig.getTotaConnect(), serviceConfig.getUseTotaV2(), address);
        // boolean defaultinterval = (boolean) SPHelper.getPreference(mContext, BesSdkConstants.BES_default_INTERVAL,
        // BesSdkConstants.BES_default_INTERVAL_VALUE);
        // long bledelay = Long.parseLong((String)
        // SPHelper.getPreference(mContext,BesSdkConstants.BES_BLE_INTERVAL,"50"));
        // long sppdelay = Long.parseLong((String)
        // SPHelper.getPreference(mContext,BesSdkConstants.BES_SPP_INTERVAL,"30"));
        //// long gattdelay = (long) SPHelper.getPreference(mContext,BesSdkConstants.BES_GATT_INTERVAL,"30");
        // if (serviceConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_SPP) {
        // if (mConfig.getTotaConnect()) {
        // sppSendDataDelay = 20;
        // } else {
        // sppSendDataDelay = 15;
        // }
        // if (USER_FLAG == 0) {
        // sppSendDataDelay = 30;
        // }
        // if (defaultinterval == false) {
        // sppSendDataDelay = sppdelay;
        // }
        // } else if (serviceConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_USB) {
        // sppSendDataDelay = 5;
        // if (defaultinterval == false) {
        // sppSendDataDelay = sppdelay;
        // }
        // }
        // else {
        // sppSendDataDelay = 50;
        // if (defaultinterval == false) {
        // sppSendDataDelay = bledelay;
        // }
        //
        // }
        sppSendDataDelay = 0;
        confirmSendDataDelay = sppSendDataDelay;
        if (USER_FLAG < 1) {
            sendPackageWithAck = serviceConfig.getCurAckType();
        }
        if (USER_FLAG == -1) {
            imageSideSelection = serviceConfig.getImageSideSelection();
            mOtaCMD.setImageSideSelection(imageSideSelection == 4 ? 1 : imageSideSelection);
        }

        curUser = serviceConfig.getCurUser();
        curUpgateType = serviceConfig.getCurUpgateType();

        LOG(TAG, "BesOtaService Protocol: --------" + serviceConfig.getDeviceProtocol());
        startConnect(serviceConfig);
    }

    // ------------------------ConnectionListener-----------------------------------
    @Override
    public void onStatusChanged(HmDevice device, int status, DeviceProtocol protocol) {
        super.onStatusChanged(device, status, protocol);
        LOG(TAG, "onStatusChanged: ------" + status);
        if (status == BES_CONNECT_SUCCESS && !mConfig.getTotaConnect()) {
            roleSwitchDisconnect = false;
            connectRetryTimes = 0;
            LOG(TAG, "onStatusChanged: -----true");
            callBackStateChangedMessage(BES_CONNECT_SUCCESS, "");
            if (!roleSwitchRandomID.isEmpty() && mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_SPP) {
                stopSppRoleSwitchTimer();
            }
            try {
                Thread.sleep(OTA_TIME_OUT);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (USER_FLAG == 1) {
                sendGetProtocolVersionData();
                // getCurrentVersion();
            } else if (USER_FLAG == 0) {
                // getCurrentVersion();
                sendSetUserData();
            }
        } else if (status != BES_CONNECT_SUCCESS) {
            if (mOTAStatus == STATUS_CANCELED || mOTAStatus == STATUS_FAILED) {
                return;
            }
            if (isSppRoleSwitch) {
                startConnect(mConfig);
                return;
            }
            if (mOTAStatus != STATUS_UNKNOWN) {
                if (mOTAStatus != STATUS_SUCCEED && mOTAStatus != STATUS_CANCELED && mOTAStatus != STATUS_FAILED
                        && !roleSwitchRandomID.isEmpty()) {
                    LOG(TAG, "onStatusChanged: -----------" + roleSwitchRandomID);
                    // role switch
                    if (mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_BLE) {
                        scanToReConnected();
                    } else if (mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_SPP
                            || mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_GATT_BR_EDR) {
                        Log.i(TAG, "onStatusChanged: ---------mDeviceProtocol == DeviceProtocol.PROTOCOL_SPP");
                        startConnect(mConfig);
                    }
                } else if (mOTAStatus == STATUS_SUCCEED) {
                    // reconnect after ota success
                    // sendDataDelay(besOtaMsgHandler, MSG_OTA_OVER_RECONNECT, 15000);
                } else {
                    LOG(TAG, "onStatusChanged: ------------22222");
                    callBackStateChangedMessage(BES_CONNECT_ERROR, "");
                }
                return;
            }
            connectRetryTimes++;
            if (connectRetryTimes == 3) {
                callBackStateChangedMessage(BES_CONNECT_ERROR, "");
                return;
            }
            startConnect(mConfig);
        }
    }

    @Override
    public void callBackTotaConnectState(boolean state) {
        super.callBackTotaConnectState(state);
        Log.i(TAG, "callBackTotaConnectState: ------" + state);
        if (state) {
            roleSwitchDisconnect = false;
            connectRetryTimes = 0;
            LOG(TAG, "onStatusChanged: -----true");
            callBackStateChangedMessage(BES_CONNECT_SUCCESS, "");
            if (!roleSwitchRandomID.isEmpty() && mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_SPP) {
                stopSppRoleSwitchTimer();
            }
            try {
                Thread.sleep(OTA_TIME_OUT);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (USER_FLAG == 1) {
                sendGetProtocolVersionData();
            } else if (USER_FLAG == 0) {
                // getCurrentVersion();
                sendSetUserData();
            }
        }
    }

    @Override
    public void onDataReceived(BaseMessage deviceMessage) {
        super.onDataReceived(deviceMessage);
        if ((mConfig.getTotaConnect() && !totauccess) || mOtaCMD == null) {
            return;
        }
        byte[] receiveData = (byte[]) deviceMessage.getMsgContent();
        LOG(TAG, "onDataReceived encode: ----" + ArrayUtil.toHex(receiveData));
        if (!sendPackageWithAck && receiveData[0] == (byte) 0x8b) {
            return;
        }
        if (mConfig.getTotaConnect() && receiveData.length > 4) {
            byte[] contentData = new byte[receiveData.length - 4];
            System.arraycopy(receiveData, 4, contentData, 0, receiveData.length - 4);
            receiveData = contentData;
        }
        LOG(TAG, "onDataReceived: ----" + ArrayUtil.toHex(receiveData));
        int result = mOtaCMD.receiveData(receiveData, mContext, curOtaResult, sendPackageWithAck);
        if (result != 0) {
            curOtaResult = result;
        }
        LOG(TAG, "onDataReceived: -----" + curOtaResult);
        if (result == OTA_CMD_ADJUST_INTERVAL) {
            int curAdjustInterval = mOtaCMD.getCurAdjustInterval();
            if (curAdjustInterval == 0) {
                sppSendDataDelay = confirmSendDataDelay;
            } else {
                sppSendDataDelay = curAdjustInterval;
            }
        } else if (result == OTA_CMD_GET_HW_INFO) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_VERSION_TIME_OUT);
            sendData(mOtaCMD.getCurCheckSegmentLengthCMD());
            if (isSppRoleSwitch) {
                isSppRoleSwitch = false;
                startOta();
                return;
            }
            getVersionRetryTimes = 0;
            if (roleSwitchRandomID.length() > 0 && mOTAStatus != STATUS_SUCCEED) {
                startOta();
                return;
            }
            callBackStateChangedMessage(result, mOtaCMD.getCurrentVersion());
        } else if (result == OTA_CMD_SEND_VERIFY_BTN_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_VERIFY_BTH_TIME_OUT);
            callBackStateChangedMessage(result, "");
            sendUpgrateTypeData();
        } else if (result == OTA_CMD_GET_PROTOCOL_VERSION) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_PROTOCOL_VERSION_TIME_OUT);
            getProtocolRetryTimes = 0;
            callBackStateChangedMessage(result, "");
            sendSetUserData();
        } else if (result == OTA_CMD_SET_OAT_USER_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_SET_USER_TIME_OUT);
            setUserRetryTimes = 0;
            callBackStateChangedMessage(result, "");
            getCurrentVersion();
        } else if (result == OTA_CMD_SET_UPGRADE_TYPE_NORMAL) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_UPGRATE_TYPE_TIME_OUT);
            callBackStateChangedMessage(result, "");
            sendGetROLESwitchRandomIDData();
        } else if (result == OTA_CMD_SET_UPGRADE_TYPE_FAST) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_UPGRATE_TYPE_TIME_OUT);
            callBackStateChangedMessage(result, "");
            sendGetROLESwitchRandomIDData();
        } else if (result == OTA_CMD_ROLESWITCH_GET_RANDOMID) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_RANDOMID_TIME_OUT);
            roleSwitchRandomID = mOtaCMD.getRoleSwitchRandomID();
            LOG(TAG, "onDataReceived roleSwitchRandomID: -----" + roleSwitchRandomID);
            callBackStateChangedMessage(result, roleSwitchRandomID);
            sendSelectSideData();
        } else if (result == OTA_CMD_SELECT_SIDE_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_SELECT_SIDE_TIME_OUT);
            callBackStateChangedMessage(result, "");
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_CHECK_BREAK_POINT_TIME_OUT);
            otaSendData(mOtaCMD.getCheckBreakPointCMD(mContext));
        } else if (result == OTA_CMD_BREAKPOINT_CHECK_80) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CHECK_BREAK_POINT_TIME_OUT);
            String isMultiDevices = (String) SPHelper.getPreference(mContext, BES_OTA_IS_MULTIDEVICE_UPGRADE, "");
            boolean bleOtaAutoTest =
                    (boolean) SPHelper.getPreference(mContext, BES_BLE_OTA_AUTO_TEST, BES_BLE_OTA_AUTO_TEST_VALUE);
            if (isMultiDevices.equals(BES_OTA_IS_MULTIDEVICE_UPGRADE) || bleOtaAutoTest) {
                otaSendData(mOtaCMD.getStartOTAPacketCMD(mRemoteOTAConfig.getLocalPath()));
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_START_OTA_PACKAGE_TIME_OUT);
            } else {
                // show config
                callBackStateChangedMessage(result, "");
            }
        } else if (result == OTA_CMD_BREAKPOINT_CHECK_80_NO_CHANGE) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
            otaSendData(mOtaCMD.getStartOTAPacketCMD(mRemoteOTAConfig.getLocalPath()));
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_START_OTA_PACKAGE_TIME_OUT);
        } else if (result == OTA_CMD_BREAKPOINT_CHECK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CHECK_BREAK_POINT_TIME_OUT);
            removeTimeoutMsg(besOtaMsgHandler, MSG_START_OTA_PACKAGE_TIME_OUT);
            callBackStateChangedMessage(result, "");
            if (curUser == USER_MULTIPLE) {
                // 设置binIdentifier
                mOtaCMD.getStartOTAPacketCMD(mRemoteOTAConfig.getLocalPath());
            }
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_SET_OTA_CONFIG_TIME_OUT);
            otaSendData(mOtaCMD.getOTAConfigureCMD(mRemoteOTAConfig.getLocalPath(), mContext));
        } else if (result == OTA_CMD_SEND_OTA_DATA) {
            mOtaCMD.notifySuccess();
            besSendData();
        } else if (result == OTA_CMD_SEND_CONFIGURE_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_SET_OTA_CONFIG_TIME_OUT);
            roleSwitchDisconnect = false;
            curOtaResult = OTA_CMD_SEND_OTA_DATA;
            mOTAStatus = STATUS_UPDATING;
            callBackStateChangedMessage(result, "");
            besSendData();
        } else if (result == OTA_CMD_CRC_CHECK_PACKAGE_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
            callBackStateChangedMessage(result, "crc check package ok");
            getCrcConfirmRetryTimes = 0;
            crcPackageRetryTimes = 0;
            curOtaResult = OTA_CMD_SEND_OTA_DATA;
            curPacketData = null;
            besSendData();
        } else if (result == OTA_CMD_WHOLE_CRC_CHECK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
            mOTAStatus = STATUS_VERIFYING;
            besSendData();
        } else if (result == OTA_CMD_DISCONNECT) {
            callBackStateChangedMessage(result, "");
            if (roleSwitchRandomID.length() > 0) {
                roleSwitchDisconnect = true;
            }
            if (mOTAStatus == STATUS_SUCCEED) {
                sendDataDelay(besOtaMsgHandler, OTA_CMD_DISCONNECT, OTA_TIME_OUT);
            }
        } else if (result == BesOTAConstants.OTA_CMD_ROLESWITCH_COMPLETE) {
            callBackStateChangedMessage(result, "");
            if (isSppRoleSwitch) {
                return;
            }
            isSppRoleSwitch = true;
            // 检测 spp role switch 断连
            startSppRoleSwitchTimer();
        } else if (result == BesOTAConstants.OTA_CMD_WHOLE_CRC_CHECK_OK) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
            if (USER_FLAG == -1) {
                mOTAStatus = STATUS_SUCCEED;
                callBackSuccessMessage(result);
                SPHelper.removePreference(mContext,
                        BesOTAConstants.BES_OTA_RANDOM_CODE_LEFT
                                + (mConfig.getDeviceProtocol() == PROTOCOL_BLE ? mConfig.getDevice().getBleAddress()
                                        : mConfig.getDevice().getDeviceMAC()));
                return;
            }
            mOTAStatus = STATUS_VERIFIED;
            callBackStateChangedMessage(result, "");
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT);
            otaSendData(mOtaCMD.getImageOverwritingConfirmationPacketCMD());
        } else if (result == BesOTAConstants.OTA_CMD_IMAGE_OVER_CONFIRM) {
            LOG(TAG, "onDataReceived: -------ota success");
            removeTimeoutMsg(besOtaMsgHandler, MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT);
            mOTAStatus = STATUS_SUCCEED;
            callBackSuccessMessage(result);
            SPHelper.removePreference(mContext,
                    BesOTAConstants.BES_OTA_RANDOM_CODE_LEFT
                            + (mConfig.getDeviceProtocol() == PROTOCOL_BLE ? mConfig.getDevice().getBleAddress()
                                    : mConfig.getDevice().getDeviceMAC()));
        } else if (result == BesOTAConstants.OTA_CMD_CRC_CHECK_PACKAGE_ERROR && crcPackageRetryTimes < 5) {
            removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
            crcPackageRetryTimes++;
            callBackStateChangedMessage(result, "" + crcPackageRetryTimes);
            // mOtaCMD.crcConfirmError();
            curOtaResult = OTA_CMD_SEND_OTA_DATA;
            curSendCount = 0;
            besSendData();
        } else if (result == OTA_CMD_RETURN) {
            LOG(TAG, "onDataReceived: OTA_CMD_RETURN------------OTA_CMD_RETURN");
        }
        // tota相关需要修改
        else if (receiveData[0] == (byte) 0x00 && receiveData[1] == (byte) 0x10 && receiveData[2] == (byte) 0x10) {
            return;
        } else if (receiveData[0] == (byte) 0x63 && receiveData[1] == (byte) 0x6f && receiveData[2] == (byte) 0x6e) {
            return;
        } else if (result == OTA_START_OTA_ERROR || result == OTA_CMD_SELECT_SIDE_ERROR
                || result == OTA_CMD_SEND_CONFIGURE_ERROR || result == OTA_CMD_CRC_CHECK_PACKAGE_ERROR
                || result == OTA_CMD_WHOLE_CRC_CHECK_ERROR || result == OTA_CMD_IMAGE_OVER_CONFIRM_ERROR
                || result == OTA_CMD_SET_OAT_USER_ERROR || result == OTA_START_DEVICE_LOW_BATTERY_ERROR) {
            if (result == BesOTAConstants.OTA_CMD_CRC_CHECK_PACKAGE_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
            } else if (result == BesOTAConstants.OTA_CMD_SET_OAT_USER_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_SET_USER_TIME_OUT);
                setUserRetryTimes = 0;
            } else if (result == BesOTAConstants.OTA_CMD_SEND_CONFIGURE_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_SET_OTA_CONFIG_TIME_OUT);
            } else if (result == OTA_START_DEVICE_LOW_BATTERY_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_SET_USER_TIME_OUT);
            } else if (result == OTA_CMD_IMAGE_OVER_CONFIRM_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT);
            } else if (result == OTA_CMD_WHOLE_CRC_CHECK_ERROR) {
                removeTimeoutMsg(besOtaMsgHandler, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
            }
            Log.i(TAG, "error onDataReceived: ----" + ArrayUtil.toHex(receiveData));
            mOTAStatus = STATUS_FAILED;
            callBackOTAStatusChanged(mOTAStatus);
            callBackErrorMessage(result);
            destoryVariable();
        }
    }

    @Override
    public void notifyWrite(int state) {
        super.notifyWrite(state);
        if (state == BES_NOTIFY_SUCCESS) {
            if (curOtaResult == OTA_CMD_SEND_OTA_DATA && sendPackageWithAck == false
                    && (USER_FLAG < 1 || !isWithoutResponse)) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(10);
                            notifyRetryTimes = 0;
                            mOtaCMD.notifySuccess();
                            sendPacketData();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        } else {
            // retry
            if (curOtaResult == OTA_CMD_SEND_OTA_DATA && sendPackageWithAck == false
                    && (USER_FLAG < 1 || !isWithoutResponse)) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            notifyRetryTimes++;
                            if (notifyRetryTimes == 3) {
                                callBackErrorMessage(BES_NOTIFY_ERROR);
                                return;
                            }
                            sendPacketData();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    }

    @Override
    public HmDevice getDevice() {
        return mConfig.getDevice();
    }

    @Override
    public RemoteOTAConfig getOtaConfig() {
        return mRemoteOTAConfig;
    }

    // ------------------------OTATask-----------------------------------
    @Override
    public void setOtaConfig(RemoteOTAConfig config) {
        File file = new File(config.getLocalPath());
        if (!file.exists()) {
            callBackErrorMessage(OTA_START_OTA_ERROR);
            mOTAStatus = STATUS_FAILED;
            callBackOTAStatusChanged(mOTAStatus);
            return;
        }
        if (imageSideSelection == 4) {
            if (config.getWhatsNewContent("") == null) {
                return;
            }
            File file2 = new File(config.getWhatsNewContent(""));
            if (!file2.exists()) {
                callBackErrorMessage(OTA_START_OTA_ERROR);
                mOTAStatus = STATUS_FAILED;
                callBackOTAStatusChanged(mOTAStatus);
                return;
            }
        }
        mRemoteOTAConfig = config;
    }

    @Override
    public OTAStatus getOTAStatus() {
        return mOTAStatus;
    }

    @Override
    public int getCurrentProgress() {
        return Float.valueOf(progress).intValue();
    }

    @Override
    public OTADfuInfo requestDFUInfo() {
        return mOTADfuInfo;
    }

    @Override
    public void preTransferInit() {
    }

    @Override
    public boolean startDataTransfer(OTADfuInfo dufInfo, StatusListener listener) {
        LOG(TAG, "startDataTransfer :" + dufInfo);
        if (curOtaResult == OTA_CMD_BREAKPOINT_CHECK_80) {
            otaSendData(mOtaCMD.getStartOTAPacketCMD(mRemoteOTAConfig.getLocalPath()));
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_START_OTA_PACKAGE_TIME_OUT);
            return true;
        }
        if (dufInfo != null) {
            mOTADfuInfo = dufInfo;
        }
        if (listener != null) {
            mStatusListener = listener;
        }
        if (checkOtaState() == false) {
            callBackErrorMessage(OTA_START_OTA_ERROR);
            mOTAStatus = STATUS_FAILED;
            callBackOTAStatusChanged(mOTAStatus);
            return false;
        }
        boolean bleOtaAutoTest =
                (boolean) SPHelper.getPreference(mContext, BES_BLE_OTA_AUTO_TEST, BES_BLE_OTA_AUTO_TEST_VALUE);
        if (mOTADfuInfo.getBreakpoint() == 0 || bleOtaAutoTest) {
            SPHelper.removePreference(mContext,
                    BesOTAConstants.BES_OTA_RANDOM_CODE_LEFT
                            + (mConfig.getDeviceProtocol() == PROTOCOL_BLE ? mConfig.getDevice().getBleAddress()
                                    : mConfig.getDevice().getDeviceMAC()));
        }
        if (curOtaResult == OTA_CMD_SEND_OTA_DATA && mOTAStatus != STATUS_PAUSED) {
            return false;
        }
        startOta();
        return true;
    }

    @Override
    public boolean startDataTransfer(OTADfuInfo dufInfo, int threshold, boolean allowBackground,
            StatusListener listener) {
        return false;
    }

    @Override
    public boolean stopDataTransfer() {
        LOG(TAG, "stopDataTransfer");
        mOTAStatus = STATUS_CANCELED;
        callBackOTAStatusChanged(mOTAStatus);
        if (mLeScanner != null) {
            mLeScanner.stopScan(mCallback);
            mLeScanner = null;
        }
        sendOtaExitData();
        destoryVariable();
        return true;
    }

    @Override
    public boolean pausedDataTransfer() {
        mOTAStatus = STATUS_PAUSED;
        return true;
    }

    @Override
    public void postTransferCleanup() {
    }

    @Override
    public boolean applyNewFirmware(int threshold) {
        return false;
    }

    @Override
    public void registerOTAStatusListener(StatusListener listener) {
    }

    @Override
    public void unregisterOTAStatusListener(StatusListener listener) {
    }

    private void callBackOTAStatusChanged(OTAStatus newStatus) {
        if (mStatusListener != null) {
            mStatusListener.onOTAStatusChanged(newStatus, mConfig.getDevice());
        }
    }

    private void callBackOTAProgressChanged(int progress) {
        if (mStatusListener != null) {
            mStatusListener.onOTAProgressChanged(progress, mConfig.getDevice());
        }
    }
    // ---------------------------------------------------------------------------------

    private boolean checkOtaState() {
        boolean s = true;
        if (mRemoteOTAConfig == null || mRemoteOTAConfig.getLocalPath() == null
                || !(new File(mRemoteOTAConfig.getLocalPath()).exists())) {
            s = false;
        }
        return s;
    }

    public void destoryVariable() {
        boolean bleOtaAutoTest =
                (boolean) SPHelper.getPreference(mContext, BES_BLE_OTA_AUTO_TEST, BES_BLE_OTA_AUTO_TEST_VALUE);
        if (bleOtaAutoTest) {
            disconnected();
        }
        if (mOtaCMD != null) {
            mOtaCMD.destoryVariable();
            mOtaCMD = null;
        }
        roleSwitchRandomID = "";
        mRemoteOTAConfig = null;
        mOTADfuInfo = null;
        mStatusListener = null;
        curOtaResult = 0;
    }

    public void getCurrentVersion() {
        if (mOtaCMD == null) {
            return;
        }
        LOG(TAG, "getCurrentVersion");
        mOTAStatus = STATUS_STARTED;
        otaSendData(mOtaCMD.getCurrentVersionCMD());
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_VERSION_TIME_OUT);
    }

    private void startOta() {
        LOG(TAG, "startOta: ------------");
        curOtaResult = 0;
        mOTAStatus = STATUS_STARTED;
        callBackOTAStatusChanged(mOTAStatus);
        try {
            Thread.sleep(OTA_TIME_OUT);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        sendUpgrateTypeData();
        // sendGetROLESwitchRandomIDData();
    }

    private void sendGetProtocolVersionData() {
        LOG(TAG, "sendGetProtocolVersionData");
        otaSendData(mOtaCMD.getOtaProtocolVersionCMD(currentOrLegacy));
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_PROTOCOL_VERSION_TIME_OUT);
        Log.i(TAG, "addTimeOutMsg MSG_GET_PROTOCOL_VERSION_TIME_OUT: ---------" + besOtaMsgHandler);
    }

    private void sendSetUserData() {
        LOG(TAG, "sendSetUserData");
        otaSendData(mOtaCMD.getSetOtaUserCMD(curUser));
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_SET_USER_TIME_OUT);
    }

    private void sendOtaExitData() {
        LOG(TAG, "sendOtaExitData");
        if (mOtaCMD != null) {
            otaSendData(mOtaCMD.getOtaExitCMD());
        }
    }

    private void sendGetROLESwitchRandomIDData() {
        if (!roleSwitchRandomID.isEmpty()) {
            sendSelectSideData();
            return;
        }

        otaSendData(mOtaCMD.getROLESwitchRandomIDCMD());
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_RANDOMID_TIME_OUT);
    }

    private void sendUpgrateTypeData() {
        otaSendData(mOtaCMD.getSetUpgrateTypeCMD(curUpgateType));
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_UPGRATE_TYPE_TIME_OUT);
    }

    private void sendSelectSideData() {
        otaSendData(mOtaCMD.getSelectSideCMD());
        addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_SELECT_SIDE_TIME_OUT);
    }

    private void besSendData() {
        if (mOTAStatus == STATUS_PAUSED || mOtaCMD == null) {
            return;
        }
        if (curPacketData == null) {
            curPacketData = mOtaCMD.getPacketData(mRemoteOTAConfig.getLocalPath(),
                    (mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_BLE
                            || mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_GATT_BR_EDR));
            curSendCount = 0;
            if (curPacketData == null) {
                otaSendData(mOtaCMD.get88CMD());
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
                return;
            }
            curSendLength = mOtaCMD.getCurSendLength();

            progress = mOtaCMD.besOtaProgress(curSendLength);
            if (progress.length() > 0) {
                callBackOTAProgressChanged(Float.valueOf(progress).intValue());
                callBackStateChangedMessage(OTA_SEND_DATA_PROGRESS, progress);
            }
        }

        byte[] data = curPacketData[curSendCount];
        if (curSendCount == curPacketData.length - 1) {
            byte[] crcData = new byte[4];
            System.arraycopy(data, data.length - 4, crcData, 0, 4);
            mOtaCMD.refreshConfirmCrc(crcData);
            addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
            otaSendData(data);
            return;
        }
        boolean ret = otaSendDataWithoutResponse(data);
        if (ret) {
            // curSendLength +=data.length;
            // progress = mOtaCMD.besOtaProgress(curSendLength);
            // if (progress.length() > 0) {
            // callBackOTAProgressChanged(Float.valueOf(progress).intValue());
            // callBackStateChangedMessage(OTA_SEND_DATA_PROGRESS, progress);
            // }
            curSendCount++;
        }
        // sendHandlerData(besOtaMsgHandler, OTA_CMD_SEND_OTA_DATA);
        sendDataDelay(besOtaMsgHandler, OTA_CMD_SEND_OTA_DATA, 1);

        // sendPacketDataDelay(sppSendDataDelay);
        // if ((USER_FLAG == 1 && isWithoutResponse) || ((mConfig.getDeviceProtocol() == PROTOCOL_SPP) &&
        // !sendPackageWithAck)) {
        // sendPacketDataDelay(sppSendDataDelay);
        // } else {
        // sendPacketData();
        // }
        // sendHandlerData(besOtaMsgHandler, OTA_CMD_SEND_OTA_DATA);
    }

    private boolean sendPacketData() {
        if (!isConnect) {
            return false;
        }
        // if (roleSwitchDisconnect || isConnect == false || isSppRoleSwitch) {
        // return false;
        // }
        synchronized (mOtaLock) {
            if (mRemoteOTAConfig == null || mOtaCMD == null) {
                return false;
            }
            byte[] data = mOtaCMD.getDataPacketCMD(mRemoteOTAConfig.getLocalPath(),
                    (mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_BLE
                            || mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_GATT_BR_EDR));
            if (data[0] != (byte) 0x85) {
                curOtaResult = 0;
            }
            if (data[0] == (byte) 0x82) {
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT);
                sendDataDelay(besOtaMsgHandler, OTA_CMD_SEND_82, 50);
                return true;
            }
            if (mOtaCMD == null) {
                return false;
            }
            progress = mOtaCMD.besOtaProgress();
            Log.i(TAG, "progress: --------" + progress);
            if (!progress.isEmpty()) {
                LOG(TAG, "sendPacketData: -----" + progress);
                callBackOTAProgressChanged(Float.valueOf(progress).intValue());
                callBackStateChangedMessage(OTA_SEND_DATA_PROGRESS, progress);
            }

            if (curOtaResult != 0 && USER_FLAG == 1 && isWithoutResponse) {
                return otaSendDataWithoutResponse(data);
            }

            return otaSendData(data);
        }
    }

    private void sendPacketDataDelay(long millis) {
        LOG(TAG, "sendPacketDataDelay----");
        sendDataDelay(besOtaMsgHandler, OTA_CMD_SEND_OTA_DATA, millis);
    }

    private boolean otaSendData(byte[] data) {
        if (mOTAStatus == STATUS_PAUSED) {
            return false;
        }
        return sendData(data);
    }

    private boolean otaSendDataWithoutResponse(byte[] data) {
        if (mOTAStatus == STATUS_PAUSED) {
            return false;
        }
        return sendDataWithoutResponse(data);
    }

    private void scanToReConnected() {
        curOtaResult = 0;
        mOTAStatus = STATUS_REBOOT;
        LOG(TAG, "scanToReConnected: -----------");
        if (mLeScanner != null) {
            mLeScanner.stopScan(mCallback);
            mLeScanner = null;
        }

        scanSuccess = false;
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(OTA_TIME_OUT);
                    LOG(TAG, "scanSuccess: --------" + scanSuccess);
                    if (!scanSuccess) {
                        LOG(TAG, "!scanSuccess: --------");
                        scanToReConnected();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        BluetoothAdapter mBluetoothAdapter = BtHeleper.getBluetoothAdapter(mContext);
        mLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
        mLeScanner.startScan(null, new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(),
                mCallback);
    }

    private void startSppRoleSwitchTimer() {
        LOG(TAG, "startSppRoleSwitchTimer----");
        stopSppRoleSwitchTimer();
        sppRoleSwitchTimes = 0;
        sppRoleSwitchTimer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                sppRoleSwitchTimes++;
                if (sppRoleSwitchTimes > 5) {
                    stopSppRoleSwitchTimer();
                    mDeviceConnector.disconnect(mConfig.getDevice());
                }
            }
        };
        sppRoleSwitchTimer.schedule(task, 0, 1000);
    }

    private void stopSppRoleSwitchTimer() {
        LOG(TAG, "stopSppRoleSwitchTimer----");
        if (sppRoleSwitchTimer != null) {
            sppRoleSwitchTimer.cancel();
            sppRoleSwitchTimer = null;
        }
    }

    public void removeHandler() {
        if (null != besOtaMsgHandler) {
            besOtaMsgHandler.removeCallbacksAndMessages(null);
        }
    }

    private final android.bluetooth.le.ScanCallback mCallback = new android.bluetooth.le.ScanCallback() {
        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            LOG(TAG, "onScanFailed: ---------fail");
            scanToReConnected();
        }

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            scanSuccess = true;
            String resultStr = ArrayUtil.bytesToHexString(result.getScanRecord().getBytes());
            String[] all = resultStr.split("03ff");
            String needStr;
            if (resultStr.contains("03ff03ff")) {
                // 特殊判断
                String[] allSp = resultStr.split("03ff03ff");
                if (allSp.length > 1) {
                    // 如果allSp[1]都是0说明是最后一个否则为其他的03ff03ff出现
                    String spStr = allSp[1];
                    boolean zero = true;
                    for (int i = 0; i < spStr.length(); i++) {
                        String singleStr = spStr.substring(i, i + 1);
                        if (singleStr.equals("0") == false) {
                            zero = false;
                            break;
                        }
                    }
                    if (zero) {
                        needStr = "03ff";
                    } else {
                        needStr = all[all.length - 1];
                        if (needStr.length() < 4) {
                            return;
                        }
                        needStr = needStr.substring(0, 4);
                    }
                } else {
                    needStr = "03ff";
                }
            } else if (all.length > 1) {
                needStr = all[all.length - 1];
                if (needStr.length() < 4) {
                    return;
                }
                needStr = needStr.substring(0, 4);
            } else {
                return;
            }
            if (needStr.equals(roleSwitchRandomID)) {
                mLeScanner.stopScan(mCallback);
                mLeScanner = null;
                BluetoothDevice device = result.getDevice();
                if (device != null) {
                    if (mConfig.getDeviceProtocol() == DeviceProtocol.PROTOCOL_BLE) {
                        mConfig.getDevice().setBleAddress(device.getAddress());
                    } else {
                        mConfig.getDevice().setDeviceMAC(device.getAddress());
                    }
                    startConnect(mConfig);
                }
            }
        }
    };

    private final Handler besOtaMsgHandler = new Handler(mHandlerThread.getLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            LOG(TAG, "handleMessage: -----" + msg.what);
            if (!isConnect || isSppRoleSwitch) {
                return;
            }
            switch (msg.what) {
            case OTA_CMD_SEND_82:
                break;
            case MSG_GET_VERSION_TIME_OUT:
                if (getVersionRetryTimes > 2) {
                    callBackErrorMessage(msg.what);
                } else {
                    getVersionRetryTimes++;
                    getCurrentVersion();
                }
                break;
            case MSG_SET_OTA_CONFIG_TIME_OUT:
                if (mOtaCMD != null && mRemoteOTAConfig != null)
                    otaSendData(mOtaCMD.getOTAConfigureCMD(mRemoteOTAConfig.getLocalPath(), mContext));
                break;
            case OTA_CMD_DISCONNECT:
                disconnected();
                break;
            case MSG_GET_RANDOMID_TIME_OUT:
                callBackStateChangedMessage(MSG_GET_RANDOMID_TIME_OUT, "");
                sendSelectSideData();
                break;
            case MSG_OTA_OVER_RECONNECT:
                if (!roleSwitchRandomID.isEmpty()) {
                    scanToReConnected();
                } else {
                    startConnect(mConfig);
                }
                break;
            case MSG_GET_PROTOCOL_VERSION_TIME_OUT:
                if (!roleSwitchRandomID.isEmpty()) {
                    disconnected();
                    return;
                }
                if (USER_FLAG == 1) {
                    sendGetProtocolVersionData();
                    /**
                    if (getProtocolRetryTimes > 2 || !isConnect) {
                        getProtocolRetryTimes = 0;
                        mOTAStatus = STATUS_FAILED;
                        callBackErrorMessage(MSG_GET_PROTOCOL_VERSION_TIME_OUT);
                        mOTAStatus = STATUS_CANCELED;
                        destoryVariable();
                    } else {
                        getProtocolRetryTimes ++;
                    }**/
                    return;
                }
                sendUpgrateTypeData();
                break;
            case MSG_GET_UPGRATE_TYPE_TIME_OUT:
                callBackStateChangedMessage(MSG_GET_UPGRATE_TYPE_TIME_OUT, "");
                sendGetROLESwitchRandomIDData();
                break;
            case MSG_GET_SELECT_SIDE_TIME_OUT:
                LOGAAA(TAG, "handleMessage: -----MSG_GET_SELECT_SIDE_TIME_OUT");
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_CHECK_BREAK_POINT_TIME_OUT);
                otaSendData(mOtaCMD.getCheckBreakPointCMD(mContext));
                break;
            case MSG_GET_CHECK_BREAK_POINT_TIME_OUT:
                LOGAAA(TAG, "handleMessage: -----MSG_GET_CHECK_BREAK_POINT_TIME_OUT");
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_GET_CHECK_BREAK_POINT_TIME_OUT);
                otaSendData(mOtaCMD.getCheckBreakPointCMD(mContext));
                break;
            case OTA_CMD_SEND_OTA_DATA:
                // boolean ss = sendPacketData();
                // if (ss && curOtaResult > 0 && mOtaCMD != null) {
                // mOtaCMD.notifySuccess();
                // besSendData();
                // } else if (!ss && curOtaResult > 0 && mOtaCMD != null) {
                // besSendData();
                // }
                besSendData();
                break;
            case MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT:
                LOGAAA(TAG, "handleMessage: -----MSG_GET_CRC_CHECK_PACKAGE_TIME_OUT");
                // resend 82
                if (getCrcConfirmRetryTimes > 1) {
                    callBackErrorMessage(OTA_CMD_CRC_CHECK_PACKAGE_ERROR);
                    return;
                }
                getCrcConfirmRetryTimes++;
                if (mOtaCMD != null) {
                    besSendData();
                } else {
                    callBackErrorMessage(OTA_CMD_CRC_CHECK_PACKAGE_ERROR);
                }
                break;
            case MSG_SET_USER_TIME_OUT:
                sendSetUserData();
                /**
                if (setUserRetryTimes > 1) {
                    if (USER_FLAG == 0) {
                        getCurrentVersion();
                    } else {
                        callBackErrorMessage(OTA_CMD_SET_OAT_USER_ERROR);
                    }
                    return;
                }
                setUserRetryTimes ++;**/
                break;
            case MSG_VERIFY_BTH_TIME_OUT:
                sendUpgrateTypeData();
                break;
            case MSG_START_OTA_PACKAGE_TIME_OUT:
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_START_OTA_PACKAGE_TIME_OUT);
                otaSendData(mOtaCMD.getStartOTAPacketCMD(mRemoteOTAConfig.getLocalPath()));
                break;
            case MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT:
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_IMAGE_OVERWRITING_CONFIRMATION_TIME_OUT);
                otaSendData(mOtaCMD.getImageOverwritingConfirmationPacketCMD());
                break;
            case MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT:
                otaSendData(mOtaCMD.get88CMD());
                addTimeOutMsg(besOtaMsgHandler, OTA_TIME_OUT, MSG_SEND_WHOLE_CRC_CHECK_TIME_OUT);
                break;
            default:
                break;

            }
        }
    };
}
